/************************************************************************************************
 *   深圳市摩西尔电子有限公司 @版本所有@
 *
 *   此文件创建表格-监控器
 *
 * 修改:
 *   1. 类型 : 创建
 *      作者 : 巫昭雯
 *      时间 : 2021.9.9
 *      内容 : 所有代码
 *************************************************************************************************/


/* exported mc_flash_table */

/* global $ */
/* global mc_block_line */
/* global mc_util_is_object */


/************************************************************************************************
 * 类型:
 *    函数
 * 功能:
 *    flash表格
 * 参数:
 *    @param { Promise<Number> } row 创建表格的行数
 *    @param { Promise<Number> } col 创建表格的列数
 *    @param { Promise<String> } id_contai 容器id
 *    @param { Promise<Object> } param 扩展参数 {w,h} 每个格子的宽高
 * 返回:
 *    @returns { Promise<String> } 参数1
 * 例子:
 *    NA
 * 备注:
 *    使用如下:
 *     1. 创建对象(格子数量, 容器id)
 *     2. 表格初始化(接口tb_io_init)之前需要设置: 语言表; 默认字串;
 *     3. tb_io_on_select_chg 接口用于选中块信息更新回调
 * 修改:
 *    1. 类型 : 创建
 *       作者 : 巫昭雯
 *       时间 : 2021-09-09
 *       内容 : 所有代码
 ************************************************************************************************/
function mc_flash_table(row, col, id_contai, param) {
    if ("number" !== typeof row || "number" !== typeof col || "" === id_contai.trim()) {
        return false;
    }

    if (!mc_util_is_object(param)) {
        param = {};
    }

    // 基本参数格式是否正确
    var m_b_param = true;
    var mc_tb_wrap_div = document.getElementById(id_contai);

    if (!mc_tb_wrap_div || 0 === row || 0 === col) {
        m_b_param = false;
        return false;
    }

    // save this obj
    var m_this = this;

    // 格子总数
    var ui_grid_num = col * row;  /* eslint-disable-line */

    // 每个小格子宽高；固定
    var each_rect_width = 82;
    var each_rect_height = 82;

    set_rect_size(param.w, param.h);

    // 保存边界值:选中时不能超过框框
    var rect_x_width = each_rect_width * (col - 1);
    var rect_y_height = each_rect_height * (row - 1);

    // 设置svg宽高
    var svg_width = each_rect_width * col;
    var svg_height = each_rect_height * row;

    // 创建svg对象
    var obj_svg = new create_svg();
    var obj_svg_head = new create_nav_svg(false);
    var obj_svg_nav = new create_nav_svg();

    // 设置平铺id
    var pattern_id = id_contai + "_mc_svg_pattern";
    var pattern_rect_id = id_contai + "_tile_rect";


    // ***************** 定义id *****************
    // 该 mc_svg_tb 最外层 id
    var str_item_wrap_id = add_id_tag("item_wrap");

    // svg块id
    var mc_svg_id = id_contai + "_mc_svg";
    var select_all_div_id = id_contai + "_select_all_div";
    var svg_item_content_id = id_contai + "_svg_item_content";
    var form_box_id = id_contai + "_form_box";

    // nav id_contai
    var mc_main_wrap_id = id_contai + "_mc_main_wrap";
    var mc_head_wrap_id = id_contai + "_mc_head_wrap";
    var mc_nav_wrap_id = id_contai + "_mc_nav_wrap";

    // 选中框
    var box_selection_wrap_id = id_contai + "_box_selection_wrap_div";  /* eslint-disable-line */


    // 主题背景文字
    // 线条实例对象
    var g_obj_line = null;
    var b_has_line_func = true;
    var m_str_main_text = "";
    var m_ui_bus_idx = 0;

    // ******************** dom obj ******************** //
    var mc_svg = null;
    var svg_item_content = null;
    // 表格整体svg；控制滚动条；
    var obj_form_box = null;    /* eslint-disable-line */
    // 控制滚动条的对象
    var obj_scroll_wrap = null;
    // 保存svg的jq对象
    var $obj_svg_jq = $("#" + mc_svg_id);
    // 保存生成的对象集合;
    var arr_create_obj = [];
    // 保存框选的div集合对象
    var arr_box_select_obj = [];
    // 语言表
    var obj_lang = {};

    // ******************** const ******************** //
    // "BUS","序号", "宽度", "高度"
    var CONST_BUS = "BUS";
    var CONST_IDX = "IDX";
    var CONST_W = "W";
    var CONST_H = "H";
    // 文字key对象; 存储WH值为Number
    var m_arr_text_key = { [CONST_BUS]: "", [CONST_IDX]: "", [CONST_W]: "", [CONST_H]: ""};
    var m_arr_text_lang = {
        // mod flash
        [CONST_BUS]: CONST_BUS,
        [CONST_IDX]: CONST_IDX,
        [CONST_W]: CONST_W,
        [CONST_H]: CONST_H,
        // monitor
        "PORT": "PORT",
        "BOX_IDX": "BOX",
        "TEMP": "Temperature",
        "HUMI": "Humidity",
        "VOL": "Voltage",
        "STATUS": "Status"
    };
    // 线条偏差值
    var obj_line_dis = {
        pre: [+75, +70],
        next: [-63, +70]
    };


    // ********************************************************************* define format ********************************************************************* //
    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    添加事件监听固定格式对象函数；提供 add_eventListener_multiple_fun 函数使用
     * 参数:
     *    @param { Promise<String> } event_name 添加事件名
     *    @param { Promise<Function> } event_fun 事件调用函数
     *    @param { Promise<Boolean> } event_bubble 是否事冒泡事件；可选参数；默认 false
     * 返回:
     *    @returns { Promise<Boolean> } 添加成功=== true || 失败 === false
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.5.20
     *      内容 : 所有代码
     ************************************************************************************************/
    var obj_event_format = function (event_name, event_fun, event_bubble) {
        if ("string" !== typeof event_name || "function" !== typeof event_fun) {
            return false;
        }
        this.event_name = event_name;
        this.event_fun = event_fun;
        this.event_bubble = event_bubble || false;
        return true;
    };

    // 给生成的div添加事件监听
    var arr_point_event = [   /* eslint-disable-line */
        new obj_event_format("mouseenter", create_div_mouseenter)
        // new obj_event_format("keydown", create_div_keydown)
        // new obj_event_format("dblclick", create_div_dblclick)
    ];


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    保存生成块的位置宽高值; 注意wh值必须为number
     * 参数:
     *    NA
     * 返回:
     *    @returns { Promise<String> } 参数1
     * 例子:
     *    NA
     * 备注:
     *    1. 该对象内 map 数据格式为: key = x_y ; val = [w, h]
     *    2. 该对象内方法参数统一: x=x轴位置(最小值为1), y=y轴位置(最小值为1), w=当前位置宽度, h=当前位置高度
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-09-11
     *       内容 : 所有代码
    ************************************************************************************************/
    var m_obj_xywh = {
        map: {},
        // 设置位置宽高; param参考备注
        set: function (x, y, w, h) {
            if ("undefined" === typeof x || "undefined" === typeof y) {
                return false;
            }

            var key = x + "_" + y;
            var arr = this.map[key];

            if (!arr) {
                this.map[key] = [];
            }

            if ("number" === typeof w) {
                this.map[key][0] = w;
            }

            if ("number" === typeof h) {
                this.map[key][1] = h;
            }
            return true;
        },
        // 取值; param参考备注; @returns { Promise<Objec> } [宽,高] || false
        get: function (x, y) {
            var key = x + "_" + y;

            if (this.map[key] && this.map[key].length) {
                return this.map[key];
            }

            return false;
        },
        // 清空数据
        clear: function () {
            this.map = {};
        }
    };


    // 初始化html; 渲染表格html & 添加事件等
    function init_html() {
        obj_svg.set_pattern_id(pattern_id);
        obj_svg.set_pattern_rect_id(pattern_rect_id);
        obj_svg_head.set_row_col(1, col);
        obj_svg_nav.set_row_col(row, 1);

        // 定义html字符串
        var str_select_all_html = "<div id='" + select_all_div_id + "' class='select_all_div'></div>";
        var str_svg_main_html = "<div id=" + mc_main_wrap_id + " class='mc_svg_main_wrap'><div id='" + mc_svg_id + "' ondragstart = 'return false;' class='dbclick_unchecked mc_svg'>" + obj_svg.get_html_svg() + "</div></div>";
        var str_svg_head_html = "<div id=" + mc_head_wrap_id + " class='mc_svg_head_wrap'><div class='mc_svg_head'>" + obj_svg_head.get_html_svg() + "</div></div>";
        var str_svg_nav_html = "<div id=" + mc_nav_wrap_id + " class='mc_svg_nav_wrap'><div class='mc_svg_nav'>" + obj_svg_nav.get_html_svg() + "</div></div>";
        // 滚动条封边
        var str_scroll_html = "<div class='scroll_block scroll_ver'></div><div class='scroll_block scroll_hor'></div>";

        // 表格组合
        var str_table_html = "<div id='" + form_box_id + "' class='form_box' contenteditable='false'>" + str_select_all_html + str_svg_head_html + str_svg_main_html + str_svg_nav_html + str_scroll_html + "</div>";
        // 生成框选外层div
        // var str_boxsele_wrap_div = "<div id='" + box_selection_wrap_id + "' class='box_selection_wrap_div' style=''><div id='" + small_div_id + "' class='small_div' style=''></div></div>";

        var str_html = str_table_html;

        // 将所有输出html包裹在该item最外层
        mc_tb_wrap_div.innerHTML = "<div id='" + str_item_wrap_id + "' tabindex='0' style='height:100%' class='uncheck_focus_style'>" + str_html + "</div> ";

        // 保存对象
        // svg
        mc_svg = document.getElementById(mc_svg_id);
        $obj_svg_jq = $(mc_svg);
        svg_item_content = document.getElementById(svg_item_content_id);
        // 滚动条;
        obj_form_box = document.getElementById(form_box_id);
        obj_scroll_wrap = document.getElementById(mc_main_wrap_id);

        // 初始化线条
        if (b_has_line_func) {
            g_obj_line = new mc_block_line(mc_svg_id);
            g_obj_line.has_mark(false);
            g_obj_line.set_line_point_offst(obj_line_dis);
            g_obj_line.callback_update_dom = update_dom_queue;
        }

        init_event();
    }

    // 初始化event
    function init_event() {
        // 图层添加监听事件
        var arr_svg_item_content_event = [
            // new obj_event_format("mousemove", svg_mousemove)
            // new obj_event_format("mouseout", svg_mouseout)
        ];

        add_eventListener_multiple_fun(svg_item_content, arr_svg_item_content_event);
        scroll_event_listener(true);
    }


    // ********************************************************************* 构造函数:svg块, 坐标尺, 高亮背景 ********************************************************************* //
    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    创建主体svg平埔矩阵图层
     * 参数:
     *    NA
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.12.17
     *      内容 : 所有代码
     ************************************************************************************************/
    function create_svg() {
        // var rect_fill = "#fff";

        var rect_stroke = "#666";
        var recv_wh = (Number(each_rect_width) + Number(each_rect_height));
        var rect_stroke_dasharray = [each_rect_width, recv_wh, each_rect_height, recv_wh, each_rect_width, recv_wh, each_rect_height, recv_wh].join(",");
        // var rect_stroke_dasharray = "" + each_rect_width + "," + (Number(each_rect_width) + Number(each_rect_height)) + "";

        // var pattern_rect_id = "";
        var pattern_rect_fill = "rgba(255, 255, 255, 0.8)";
        var pattern_rect_stroke = "#000";

        // var pattern_id = "";


        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    设置pattern_id
         * 参数:
         *    @param { Promise<String> } str svg平铺pattern属性id名
         * 返回:
         *    @returns { Promise<Boolean> } true 执行成功
         * 例子:
         *    NA
         * 备注:
         *    NA
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        this.set_pattern_id = function (str) {
            if ("string" !== typeof str) {
                return false;
            }

            pattern_id = str;

            return true;
        };


        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    设置平铺内小格子rect的id
         * 参数:
         *    @param { Promise<String>} str 设置的svg平铺pattern属性内的rect的id名
         * 返回:
         *    @returns { Promise<Boolean>} true || false
         * 例子:
         *    NA
         * 备注:
         *    NA
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        this.set_pattern_rect_id = function (str) {
            if ("string" !== typeof str) {
                return false;
            }
            pattern_rect_id = str;

            return true;
        };

        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    获取生成主体svg的html字串
         * 参数:
         *    NA
         * 返回:
         *    @returns { Promise<String> } 生成主体svg的html字串
         * 例子:
         *    NA
         * 备注:
         *    NA
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        this.get_html_svg = function () {
            // 步骤
            // 设置每个小格子宽高固定值
            // 设置svg宽高;然后平铺矩阵宽高设置100%
            // 设置pattern宽高

            var pattern_width = each_rect_width / svg_width;
            var pattern_height = each_rect_height / svg_height;

            return "<svg  id='" + svg_item_content_id + "' width='" + svg_width + "' height='" + svg_height + "' version='1.1' xmlns='http://www.w3.org/2000/svg'><defs>" +
            "<pattern id='" + pattern_id + "' x='0' y='0' width='" + pattern_width + "' height='" + pattern_height + "'>" +
            "<rect class='' stroke-linecap='round' id='" + pattern_rect_id + "' x='0' y='0' width='" + each_rect_width + "' height='" + each_rect_height + "' fill='" + pattern_rect_fill + "' stroke-dasharray='" + rect_stroke_dasharray + "' stroke-width='1' stroke='" + pattern_rect_stroke + "'></rect>" +
            m_str_main_text +
            "</pattern></defs>" +
            "<rect  id='svg_item_content_rect' x='0' y='0' width='100%' height='100%' fill='url(#" + pattern_id + ")' stroke='" + rect_stroke + "' div_type='" + get_div_type_val(2) + "'></rect></svg>";
        };
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    创建导航栏svg
     * 参数:
     *    @param { Promise<Boolean> } b_nav 是否为侧边导航;  false === 头部导航(横轴) || 其他(默认侧边导航) === 侧边导航(竖轴)
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    根据输入的行列数控制显示头部以及侧边导航栏;
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.12.17
     *      内容 : 所有代码
     ************************************************************************************************/
    function create_nav_svg(b_nav) {
        // 定义侧边导航
        this.b_nav = true;

        if (false === b_nav) {
            this.b_nav = false;
        }

        // 文本
        var text_x = "";
        var text_y = "";
        var text_content = "";

        // 设置导航rect
        var nav_rect_fill = "rgba(238,238,238, 0.8)";
        var nav_rect_stroke = "#666";

        // 定义边框方向
        var rect_border_dir = "";
        var text_class = "";

        // 设置循环次数
        var loop_num = null;

        // 导航栏宽高
        var svg_div_width = 30;
        var svg_div_height = 30;

        // 边界值
        var rect_max_x = "";
        var rect_max_y = "";

        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    设置外层div的对象
         * 参数:
         *    @param { Promise<Object> } obj 外层div对象
         * 返回:
         *    NA
         * 例子:
         *    NA
         * 备注:
         *    根据外层对象设置当前图层的宽高
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        this.set_wrap_div = function (obj) {
            if ("undefined" !== typeof obj) {
                svg_div_width = obj.offsetWidth;
                svg_div_height = obj.offsetHeight;
            }
        };


        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    设置几行几列
         * 参数:
         *    @param { Promise<Number> } str_row 设置行数
         *    @param { Promise<Number> } str_col 设置列数
         * 返回:
         *    NA
         * 例子:
         *    NA
         * 备注:
         *    根据输入的行列数控制显示头部以及侧边导航栏
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        this.set_row_col = function (str_row, str_col) {
            if ("undefined" !== typeof row && "undefined" !== typeof col) {
                if (this.b_nav) {
                    loop_num = str_row;
                } else {
                    loop_num = str_col;
                }
            }
        };

        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    获取边界值 0 === x轴;other === y轴
         * 参数:
         *    @param { Promise<Object> } str 外层div对象
         * 返回:
         *    @returns { Promise<Boolean> } true 设置成功
         * 例子:
         *    NA
         * 备注:
         *    根据输入的行列数控制显示头部以及侧边导航栏
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        this.get_b_val = function (str) {
            if ("undefined" !== typeof str) {
                if ("x" === str) {
                    return rect_max_x;
                }
                return rect_max_y;
            }
            return false;
        };

        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    获取生成svg的html字串
         * 参数:
         *    NA
         * 返回:
         *    @returns { Promise<String> } 生成svg的html字串
         * 例子:
         *    NA
         * 备注:
         *    NA
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        this.get_html_svg = function () {
            var line_text_html = "";

            // 设置矩阵宽高,设置矩阵x,y轴
            var rect_width = each_rect_width;
            var rect_height = each_rect_height;
            var rect_x = "";
            var rect_y = "";
            var rect_stroke_width = 0.5;

            // 导航div里面的svg宽高；有边框差值所以+1
            var nav_sgv_width = svg_width + 1;
            var nav_svg_height = svg_height + 1;


            for (var idx = 0; idx < loop_num; idx++) {
                // 有边框差值
                rect_x = idx * rect_width + 0.5;
                rect_y = idx * rect_height + 0.3;

                text_x = rect_x + (rect_width / 2);
                // text_y = rect_y + (rect_width / 2);
                text_y = rect_y + (rect_height / 2);


                if (this.b_nav) {
                    // 侧边
                    nav_sgv_width = "100%";
                    rect_x = 0;
                    rect_width = svg_div_width;
                    text_x = rect_width / 2;
                    rect_border_dir = "rect_border_top";
                    text_class = "text_nav";
                } else {
                    // 头部
                    nav_svg_height = "100%";
                    rect_y = 0;
                    rect_height = svg_div_height;
                    text_y = rect_height / 2;
                    rect_border_dir = "rect_border_left";
                    text_class = "text_head";
                }

                text_content = Number(idx) + 1;
                line_text_html += "<rect class='" + rect_border_dir + "' x='" + rect_x + "' y='" + rect_y + "' width='" + rect_width + "' height='" + rect_height + "' fill='" +
                    nav_rect_fill + "' stroke-width='" + rect_stroke_width + "' stroke='" + nav_rect_stroke +
                    "'></rect><text class='" + text_class + "' x='" + text_x + "' y='" + text_y + "' alignment-baseline='middle' text-anchor='middle'>" + text_content + "</text>";
            }

            return "<svg  width='" + nav_sgv_width + "' height='" + nav_svg_height + "' version='1.1' xmlns='http://www.w3.org/2000/svg'>" + line_text_html + "</svg>";
        };
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    添加id关联外部标记
     * 参数:
     *    @param { Promise<String>} str 设置的id名
     * 返回:
     *    @returns { Promise<String>} 成功返回带标记的id || 返回输入参数
     * 例子:
     *    NA
     * 备注:
     *    该外部标记为调用 mc_svg_tb 对象函数的id传参
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2020.5.21
     *      内容 : 所有代码
     ************************************************************************************************/
    function add_id_tag(str) {
        if ("string" !== typeof str) {
            return str;
        }

        return id_contai + "_" + str;
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    获取div_type值;
     * 参数:
     *    @param { Promise<Number> } key 定义的 obj_div_type 对象key
     * 返回:
     *    @returns { Promise<String> } 返回相应的字符串值 || false
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2020-07-29
     *       内容 : 所有代码
    ************************************************************************************************/
    function get_div_type_val(key) {
        if ("number" !== typeof key) {
            return false;
        }

        // 定义div类型
        var obj_div_type = {
            // 生成块
            0: "create_block",
            // 编辑框
            1: "edit_box",
            // 背景小格子
            2: "svg_rect",
            // 虚点块
            3: "create_block_virtual_point"
        };

        return obj_div_type[key];
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    添加多个事件监听
     * 参数:
     *    @param { Promise<Object> } obj 添加事件监听对象
     *    @param { Promise<Array> } arr 多个事件监听数组
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    该函数不接受添加的时间事件监听不接收参数
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.5.20
     *      内容 : 所有代码
     ************************************************************************************************/
    function add_eventListener_multiple_fun(obj, arr) {
        if (obj && arr instanceof Array) {
            arr.forEach(function (item) {
                if ("object" === typeof item && item.constructor === obj_event_format && 0 !== Object.keys(item).length) {
                    obj.addEventListener(item.event_name, item.event_fun, item.event_bubble);
                }
            });
        }
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    添加或移除滚动条监听
     * 参数:
     *    @param { Promise<Boolean> } b_add 添加 === true  || 移除 === false
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.4.15
     *      内容 : 所有代码
     ************************************************************************************************/
    function scroll_event_listener(b_add) {
        if ("boolean" !== typeof b_add) {
            return;
        }

        if (b_add) {
            obj_scroll_wrap.onscroll = scroll_event;
        }
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    滚动条事件
     * 参数:
     *    NA
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    scroll_callback(); 控制联动滚动条的回调事件
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2020.4.3
     *      内容 : 所有代码
     ************************************************************************************************/
    function scroll_event() {
        set_scroll_pos(mc_main_wrap_id, this.scrollLeft, this.scrollTop);

        if ("function" === typeof scroll_callback) {
            scroll_callback(this); /* eslint-disable-line */
        }

        return;
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    设置滚动条滚动时导航栏的位置以及滚动条的位置
     * 参数:
     *    @param { Promise<String> } scroll_id 控制滚动条的id
     *    @param { Promise<String> } left 滚动条的left值
     *    @param { Promise<String> } top 滚动条的top值
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2020.4.3
     *      内容 : 所有代码
     ************************************************************************************************/
    function set_scroll_pos(scroll_id, left, top) {
        if ("undefined" === typeof scroll_id || "undefined" === typeof left || "undefined" === typeof top) {
            return;
        }

        // 使用定义的id
        // $("#" + mc_main_wrap_id).scrollTop(top).scrollLeft(left);

        // 使用传进来的id
        $("#" + scroll_id).scrollTop(top).scrollLeft(left);

        var set_left = -top;
        var set_top = -left;

        // 设置导航位置
        $("#" + mc_nav_wrap_id).css("top", set_left + "px");
        $("#" + mc_head_wrap_id).css("left", set_top + "px");

        // 联动外部侧边
        if ("function" === typeof m_this.tb_io_on_scroll) {
            m_this.tb_io_on_scroll(set_left, set_top);
        }
    }


    // ********************************************************************* 鼠标事件 ********************************************************************* //
    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    svg图层移动事件
     * 参数:
     *    @param { Promise<Object> } event 鼠标事件默认参数
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    点击鼠标左键:创建选中块
     *    点击鼠标右键:取消框选事件
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.12.17
     *      内容 : 所有代码
     ************************************************************************************************/
    // var handler = null;
    function svg_mousemove(event) {    /* eslint-disable-line */
        // console.log("[~~ move ~~]", event);

        // 阻止事件分发
        // event.stopPropagation();

        // 定义鼠标按下释放事件
        this.onmousedown = svg_mousemove_dowm;
        this.onmouseup = svg_mousemove_up;


        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    svg图层鼠标按下事件
         * 参数:
         *    @param { Promise<Object> } event_down 键盘事件默认参数
         * 返回:
         *    NA
         * 例子:
         *    NA
         * 备注:
         *    点击鼠标左键:创建选中块
         *    点击鼠标右键:取消框选事件
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        function svg_mousemove_dowm(event_down) {
            if (0 === event_down.button) {
                // console.log("svg_mousemove_dowm");
                // 当前为编辑状态
                var x_rem = event_down.offsetX / each_rect_width;
                var y_rem = event_down.offsetY / each_rect_height;

                var x_rem_floor = Math.floor(x_rem);
                var y_rem_floor = Math.floor(y_rem);

                // 点击保存当前点击位置；求出当前格子的范围
                this.keydown_left_min = x_rem_floor * each_rect_width;
                this.keydown_left_max = (x_rem_floor + 1) * each_rect_width;
                this.keydown_top_min = y_rem_floor * each_rect_height;
                this.keydown_top_max = (y_rem_floor + 1) * each_rect_height;
            }
        }


        /************************************************************************************************
         * 类型:
         *    函数
         * 功能:
         *    svg图层鼠标释放事件
         * 参数:
         *    @param { Promise<Object> } event_up 鼠标事件默认参数
         * 返回:
         *    NA
         * 例子:
         *    NA
         * 备注:
         *    NA
         * 修改:
         *   1. 类型 : 创建
         *      作者 : 巫昭雯
         *      时间 : 2019.12.17
         *      内容 : 所有代码
         ************************************************************************************************/
        function svg_mousemove_up(event_up) {
            if (0 === event_up.button) {
                // console.log("svg_mousemove_up=====")

                if (event_up.target) {
                    $("#" + mc_svg_id + " .click_create_div").css("pointer-events", "auto");

                    // 判断不是拖拽
                    var b_no_drag_left = this.keydown_left_min <= event_up.offsetX && event_up.offsetX <= this.keydown_left_max;
                    var b_no_drag_top = this.keydown_top_min <= event_up.offsetY && event_up.offsetY <= this.keydown_top_max;

                    if (b_no_drag_left && b_no_drag_top) {
                        // 点击之后没有拖拽

                        //将所有的生成点取消掉编辑状态
                        $("#" + mc_svg_id + " .click_create_div").attr("contenteditable", false);

                        var id = "click_div_" + arr_create_obj.length;   /* eslint-disable-line */
                        var arr_pre_select = [];

                        if (event_up.ctrlKey) {
                            // 多选
                            arr_pre_select = arr_box_select_obj.slice(0);
                        } else {
                            remove_selected_div_class();
                        }

                        if (b_has_line_func) {
                            var ui_cur_val = g_obj_line.get_idx(m_ui_bus_idx + "");

                            // 保存序号
                            m_arr_text_key.IDX = ui_cur_val;
                            // 点击生成
                            // create_div_mouse_click(id, this.keydown_top_min, this.keydown_left_min, ui_cur_val, "click_create_div");
                        }

                        arr_box_select_obj = arr_box_select_obj.concat(arr_pre_select);
                        return;
                    }


                    // 生成块鼠标移动事件在svg滑动时需要框选之前已选中的div
                    if (0 !== arr_create_obj.length) {
                        // set_style_after_drag("键盘事件不存在生成块", ui_selected_xy);
                    }
                }
            }
        }
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    生成块键盘按下事件(选中的生成块)
     * 参数:
     *    @param { Promise<Object>} event 键盘事件参数event
     *    @param { Promise<boolean>}  b_wrap 是否为外层区域
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2020.5.18
     *      内容 : 所有代码
     ************************************************************************************************/
    function create_div_keydown(event, b_wrap) {
        // 若取消选中则return;
        if (0 === arr_box_select_obj.length) {
            event.stopPropagation();
            return;
        }

        var key_code = event.keyCode;
        var obj_cur = event.target;

        // 框选对象
        var obj_sel = arr_box_select_obj[0];

        if (b_wrap && obj_cur !== obj_sel) {
            // 防止外层选中没有触发键盘事件
            obj_cur = obj_sel;
        }

        // 方向键
        var arr_dir_key = [37, 38, 39, 40];
        // 定义键盘功能键:enter || "shift" || ctrl || tab || capslock
        var arr_function_keys = [13, 16, 17, 20, 9];  /* eslint-disable-line */

        // 功能键 || window 键
        if (event.shiftKey || event.altKey || event.metaKey) {
            return;
        }

        // 方向键触发事件; 条件:当前不为可编辑状态时
        if (-1 !== arr_dir_key.indexOf(key_code)) {
            event.preventDefault();
            event.stopPropagation();
            create_div_keyboard_event_dir();
            return;
        }
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *   生成块 双击事件
     * 参数:
     *    @param { Promise<Object>} event 鼠标事件参数event
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    生成块 双击进入编辑状态
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2020.5.18
     *      内容 : 所有代码
     ************************************************************************************************/
    function create_div_dblclick(event) {
        // console.log("dblclick", event);

        if (!b_has_line_func) {
            var obj_cur = event.currentTarget;

            update_select_key(obj_cur.getAttribute("KEY"), true);
        }

        // 定义失焦事件
        // obj_cur.onblur = create_div_blur;
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    生成块方向键键盘事件
     * 参数:
     *    @param { Promise<Object> } event 键盘事件默认参数
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    控件方向键:
     *      左:37 === keyCode
     *      上:28 === keyCode
     *      右:39 === keyCode
     *      下:40 === keyCode
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.12.17
     *      内容 : 所有代码
     ************************************************************************************************/
    function create_div_keyboard_event_dir(event) {
        var ev = event || window.event;
        var key_code = ev.keyCode;
        // 框选对象
        var arr_selected_div = arr_box_select_obj;
        var ui_arr_len = arr_selected_div.length;

        if (!ui_arr_len) {
            return;
        }

        // 默认为选中最后一个
        var selected_div = ev.currentTarget;
        var top_pos = selected_div.offsetTop;
        var left_pos = selected_div.offsetLeft;

        var ui_x_num = Number(selected_div.getAttribute("x"));
        var ui_y_num = Number(selected_div.getAttribute("y"));


        // 选中的块不超过边界值
        var b_is_svg_box = 0 !== selected_div.offsetTop || 0 !== selected_div.offsetLeft || selected_div.offsetLeft !== rect_x_width || rect_y_height !== selected_div.offsetTop;

        if (b_is_svg_box && ev) {
            // 方向==左
            if (37 === key_code && 0 !== selected_div.offsetLeft && 1 < Math.floor(ui_x_num)) {
                left_pos = selected_div.offsetLeft - each_rect_width;
                set_choose_div_class_keydown(top_pos, left_pos, ev.ctrlKey);
                return;
            }
            // 方向==上
            if (38 === key_code && 0 !== selected_div.offsetTop && 1 < Math.floor(ui_y_num)) {
                top_pos = selected_div.offsetTop - each_rect_height;
                set_choose_div_class_keydown(top_pos, left_pos, ev.ctrlKey);
                return;
            }
            // 方向==右
            if (39 === key_code && rect_x_width !== selected_div.offsetLeft && col > ui_x_num) {
                left_pos = Number(selected_div.offsetLeft) + Number(each_rect_width);
                set_choose_div_class_keydown(top_pos, left_pos, ev.ctrlKey);
                return;
            }
            // 方向==下
            if (40 === key_code && rect_y_height !== selected_div.offsetTop && row > ui_y_num) {
                top_pos = Number(selected_div.offsetTop) + Number(each_rect_height);
                set_choose_div_class_keydown(top_pos, left_pos, ev.ctrlKey);
                return;
            }
        }
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    设置键盘事件对应方向建触发相应事件:设置选中块样式
     * 参数:
     *    @param { Promise<String> } top_pos top值
     *    @param { Promise<String> } left_pos left值
     *    @param { Promise<String> } b_multi 是否为多选
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.12.17
     *      内容 : 所有代码
     ************************************************************************************************/
    function set_choose_div_class_keydown(top_pos, left_pos, b_multi) {
        // 编辑存在的div下标
        var exist_div_idx = -1;
        var arr_create_div = arr_create_obj;
        var arr_create_div_len = arr_create_div.length;

        if (!arr_create_div_len) {
            return;
        }

        for (var idx = 0; idx < arr_create_div_len; idx++) {
            var item = arr_create_div[idx];

            if (!b_multi) {
                item.classList.remove("box_selection_creat_div");
            }

            if (item.offsetTop === Number(top_pos) && item.offsetLeft === Number(left_pos)) {
                exist_div_idx = idx;
                if (b_multi) {
                    break;
                }
            }
        }

        if (-1 !== exist_div_idx) {
            var item_exist = arr_create_div[exist_div_idx];

            if (b_multi) {
                if (-1 === arr_box_select_obj.indexOf(item_exist)) {
                    arr_box_select_obj.push(item_exist);
                }
            } else {
                arr_box_select_obj = [item_exist];
            }

            item_exist.classList.add("box_selection_creat_div");
            item_exist.focus();

            if (b_has_line_func) {
                update_select_pos(Number(item_exist.getAttribute("x")), Number(item_exist.getAttribute("y")));
            } else {
                update_select_key(item_exist.getAttribute("KEY"));
            }
        } else {
            // var id = "click_div_" + arr_create_obj.length;
            var arr_pre_select = [];

            if (b_multi) {
                // 多选
                arr_pre_select = arr_box_select_obj.slice(0);
            } else {
                remove_selected_div_class();
            }

            if (b_has_line_func) {
                var ui_cur_val = g_obj_line.get_idx(m_ui_bus_idx + "");

                // 保存序号
                m_arr_text_key.IDX = ui_cur_val;
                // create_div_mouse_click(id, top_pos, left_pos, ui_cur_val, "click_create_div");
            }

            arr_box_select_obj = arr_box_select_obj.concat(arr_pre_select);
        }
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    生成块鼠标移入事件
     * 参数:
     *    @param { Promise<Object> } event 鼠标移动事件默认参数
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    鼠标移动需要判断是单纯移动还是鼠标拖拽；
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.12.17
     *      内容 : 所有代码
     ************************************************************************************************/
    function create_div_mouseenter(event) {
        // console.log("create_div_mouseenter");
        // return;

        $("#" + mc_svg_id + " .click_create_div").css("pointer-events", "auto");

        if (0 !== event.button) {
            return;
        }

        // 鼠标移动时hover块移动
        // set_hover_div_style_mousemove(true, event);

        //  定义鼠标按下释放事件
        this.onmousedown = create_div_mouseenter_down;
        this.onmouseup = create_div_mouseenter_up;
        // this.ondblclick = create_div_dblclick;
    }


    /************************************************************************************************
    * 类型:
    *    函数
    * 功能:
    *    生成块鼠标按下事件; 鼠标移入时-->触发鼠标按下事件
    * 参数:
    *    @param { Promise<Object> } event_down 鼠标按下事件默认参数
    * 返回:
    *    NA
    * 例子:
    *    NA
    * 备注:
    *    鼠标按下事件为按下左键时才触发
    * 修改:
    *   1. 类型 : 创建
    *      作者 : 巫昭雯
    *      时间 : 2019.12.17
    *      内容 : 所有代码
    ************************************************************************************************/
    function create_div_mouseenter_down(event_down) {    /* eslint-disable-line */

    }

    /************************************************************************************************
    * 类型:
    *    函数
    * 功能:
    *    生成块鼠标释放事件; 鼠标移入时-->释放鼠标
    * 参数:
    *    @param { Promise<Object> } event_up 鼠标释放事件默认参数
    * 返回:
    *    NA
    * 例子:
    *    NA
    * 备注:
    *    鼠标释放事件为按下左键时才触发
    * 修改:
    *   1. 类型 : 创建
    *      作者 : 巫昭雯
    *      时间 : 2019.12.17
    *      内容 : 所有代码
    ************************************************************************************************/
    function create_div_mouseenter_up(event_up) {
        // console.log("create_div_mouseenter_up", event_up);
        if (0 !== event_up.button) {
            return;
        }

        event_up.stopPropagation();
        // event.preventDefault();
        var obj_cur = event_up.currentTarget;

        if (g_obj_line && b_has_line_func) {
            var obj_key = Number(g_obj_line.get_key(obj_cur));

            if (obj_key !== m_ui_bus_idx) {
                m_this.tb_io_update_text_val(m_ui_bus_idx, null, null, null, obj_cur);
            }
        }

        // 选中
        if (event_up.ctrlKey) {
            obj_cur.classList.add("box_selection_creat_div");
            if (-1 === arr_box_select_obj.indexOf(obj_cur)) {
                arr_box_select_obj.push(obj_cur);
            }
        } else {
            arr_box_select_obj = [obj_cur];
            remove_selected_div_class(obj_cur);
        }

        if (b_has_line_func) {
            update_select_pos(Number(obj_cur.getAttribute("x")), Number(obj_cur.getAttribute("y")));
        } else {
            update_select_key(obj_cur.getAttribute("KEY"));
        }
        return;
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    创建鼠标点击时的生成的div（鼠标点击生成）
     * 参数:
     *     @param { Promise<String> } id 生成div的id值;
     *     @param { Promise<String> } top 生成div的top值;
     *     @param { Promise<String> } left 生成div的left值;
     *     @param { Promise<String> } val 生成div的value值;
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    并给生成的div创建监听事件
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.12.17
     *      内容 : 所有代码
     ************************************************************************************************/
    function create_div_mouse_click(id, top, left, val) {  /* eslint-disable-line */
        var real_id = id_contai + "_" + id + "_" + (Math.random() * 1000).toFixed();
        var x_val = left / each_rect_width + 1;
        var y_val = top / each_rect_height + 1;
        var formula = val;
        var init_fml = val;
        var pos_val = "(" + x_val + ":" + y_val + ")";
        var str_div_type = get_div_type_val(0);
        var str_class_name = "click_create_div  box_selection_creat_div ";

        var str_click_div = "<div id='" + real_id + "' div_type='" + str_div_type + "' is_choose='true' tabindex='0' contenteditable='false' class='" + str_class_name + "' style='top:" + top + "px;left:" + left + "px;width:" + each_rect_width + "px;height:" + each_rect_height +
        "px;' x='" + x_val + "' y='" + y_val + "' pos='" + pos_val + "' init_fml = '" + init_fml + "'  formula='" + formula + "'>" + create_text_html(val) + "</div>";

        // 标识该位置
        m_obj_xywh.set(x_val, y_val, Number(m_arr_text_key.W), Number(m_arr_text_key.H));
        $obj_svg_jq.append(str_click_div);

        var obj_div_click = document.getElementById(real_id);

        // 添加事件
        operation_of_new_create_point(obj_div_click);
        // 设置生成之后就可以获得焦点；可触发键盘事件
        obj_div_click.focus();
        // 生成div的同时保存框选对象
        arr_box_select_obj = [obj_div_click];
        // 设置连线队列
        g_obj_line.set_queue(m_ui_bus_idx + "", obj_div_click, true);
        // 更新选中对象坐标值
        update_select_pos(Number(x_val), Number(y_val));
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    创建渲染div - mod falsh
     * 参数:
     *    @param { Promise<String> } id 生成div的id值;
     *    @param { Promise<String> } x_val 生成div的x值
     *    @param { Promise<String> } y_val 生成div的y值
     *    @param { Promise<String> } line_key 线条key
     *    @param { Promise<String> } key 生成div的唯一标记key
     *    @param { Promise<String> } inner_val 块内值
     *    @param { Promise<String> } str_class 添加的样式
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-12-09
     *       内容 : 所有代码
    ************************************************************************************************/
    function create_div_render_monitor(id, x_val, y_val, line_key , key, inner_val, str_class) {
        var real_id = id_contai + "_" + id + "_" + (Math.random() * 1000).toFixed();
        var left = each_rect_width * (x_val - 1);
        var top = each_rect_height * (y_val - 1);
        var formula = key;
        var init_fml = key;
        var pos_val = "(" + x_val + ":" + y_val + ")";
        var str_div_type = get_div_type_val(0);
        var str_class_name = "click_create_div monitor " + str_class;

        var str_click_div = "<div id='" + real_id + "' div_type='" + str_div_type + "' is_choose='true' tabindex='0' contenteditable='false' class='" + str_class_name + "' style='top:" + top + "px;left:" + left + "px;width:" + each_rect_width + "px;height:" + each_rect_height +
        "px;' x='" + x_val + "' y='" + y_val + "' pos='" + pos_val + "' init_fml = '" + init_fml + "'  formula='" + formula + "'>" + inner_val + "</div>";

        // 标识该位置
        m_obj_xywh.set(x_val, y_val, Number(m_arr_text_key.W), Number(m_arr_text_key.H));
        $obj_svg_jq.append(str_click_div);

        var obj_div_click = document.getElementById(real_id);

        // 添加事件
        operation_of_new_create_point(obj_div_click);
        // 设置生成之后就可以获得焦点；可触发键盘事件
        obj_div_click.focus();
        // 设置连线队列
        g_obj_line.set_queue(line_key + "", obj_div_click);
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    创建文本信息html; 用于模组flash
     * 参数:
     *    @param { Promise<String> } idx 当前序号值;
     * 返回:
     *    @returns { Promise<String> } html字符串
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-09-11
     *       内容 : 所有代码
    ************************************************************************************************/
    function create_text_html(idx) {
        var html = "<div class='text_wrap'>" +
                    "<div class='div_text BUS' BUD='" + m_arr_text_key.BUS + "'>" + m_arr_text_lang.BUS + ":" + m_arr_text_key.BUS + "</div>\n" +
                    "<div class='div_text IDX' IDX='" + idx + "'>" + m_arr_text_lang.IDX + ":" + idx + "</div>\n" +
                    "<div class='div_text W' W='" + m_arr_text_key.W + "'>" + m_arr_text_lang.W + ":" + m_arr_text_key.W + "</div>\n" +
                    "<div class='div_text H' H='" + m_arr_text_key.H + "'>" + m_arr_text_lang.H + ":" + m_arr_text_key.H + "</div>\n" +
                    "</div>";

        return html;
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    创建文本信息html; 用于界面 监控-温湿度,电压
     * 参数:
     *    @param { Promise<String> } str_name 下标name;
     *    @param { Promise<Object> } obj_exp 扩展数据对象;
     *    @param { Promise<String> } type 当前获取类型; "TH"=温度湿度; "VOL"=电压; "ERROR"=误码率; 为空时渲染所有
     *    @param { Promise<Array> } arr_color 文字异常颜色
     * 返回:
     *    @returns { Promise<String> } html字符串
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-11.26
     *       内容 : 所有代码
    ************************************************************************************************/
    function create_html_monitor_text(str_name, obj_exp, type, arr_color) {
        if (!obj_exp) {
            obj_exp = {};
        }

        if ("object" !== typeof arr_color ) {
            arr_color = [];
        }

        var arr_html = [
            "<div class='div_text name'>" + str_name + "</div>\n"
        ];

        switch (type) {
        case "VOL":
            arr_html.push("<div class='div_text " + arr_color[0] + " '>" + "<span lang_id='" + m_arr_text_lang.VOL + "'>" + m_arr_text_lang.VOL + "</span>" + " " + deal_value(parseFloat(obj_exp.VOL), "V") + "</div>\n");
            break;
        case "TH":
            arr_html.push("<div class='div_text " + arr_color[0] + " '>" + "<span lang_id='" + m_arr_text_lang.TEMP + "'>" + m_arr_text_lang.TEMP + "</span>" + " " + deal_value(parseFloat(obj_exp.TEMP), "℃") + "</div>\n");
            arr_html.push("<div class='div_text " + arr_color[1] + " '>" + "<span lang_id='" + m_arr_text_lang.HUMI + "'>" + m_arr_text_lang.HUMI + "</span>" + " " + deal_value(parseFloat(obj_exp.HUMI), "%") + "</div>\n");
            break;
        case "ERROR":
            arr_html.push("<div class='div_text " + arr_color[0] + " '>" + "<span lang_id='" + m_arr_text_lang.ERROR + "'>" + m_arr_text_lang.ERROR + "</span>" + " " + deal_value(obj_exp.ERROR) + "</div>\n");
            break;
        default:
            arr_html.push("<div class='div_text " + arr_color[0] + " '>" + "<span lang_id='" + m_arr_text_lang.VOL + "'>" + m_arr_text_lang.VOL + "</span>" + " " + deal_value(parseFloat(obj_exp.VOL), "V") + "</div>\n");
            arr_html.push("<div class='div_text " + arr_color[1] + " '>" + "<span lang_id='" + m_arr_text_lang.TEMP + "'>" + m_arr_text_lang.TEMP + "</span>" + " " + deal_value(parseFloat(obj_exp.TEMP), "℃") + "</div>\n");
            arr_html.push("<div class='div_text " + arr_color[2] + " '>" + "<span lang_id='" + m_arr_text_lang.HUMI + "'>" + m_arr_text_lang.HUMI + "</span>" + " " + deal_value(parseFloat(obj_exp.HUMI), "%") + "</div>\n");
            arr_html.push("<div class='div_text " + arr_color[3] + " '>" + "<span lang_id='" + m_arr_text_lang.ERROR + "'>" + m_arr_text_lang.ERROR + "</span>" + " " + deal_value(obj_exp.ERROR) + "</div>\n");
            break;
        }

        return "<div class='text_wrap'>" + arr_html.join(" ") + "</div>";

        // 处理数据,val=值; tail=值的符号
        function deal_value(val, tail) {
            if ("undefined" === typeof val || ("object" === typeof val && !val)) {
                return "--";
            }
            if ("number" === typeof val && !isFinite(val)) {
                return "--";
            }
            if ("string" !== typeof val) {
                val += "";
            }
            if (val.trim()) {
                return val + (tail ? tail : "");
            }
            return "--";
        }
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    获取分控端口html
     * 参数:
     *    @param { Promise<Object> } obj_item_ext 扩展数据对象;
     * 返回:
     *    @returns { Promise<String> } 端口html
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2022-01-04
     *       内容 : 所有代码
    ************************************************************************************************/
    function create_html_monitor_hub_port(obj_item_ext) {
        if (!obj_item_ext) {
            obj_item_ext = {};
        }
        var arr_port_status = obj_item_ext.STATUS || [];
        var ui_port_cnt = 8;
        var str_html = "<div class='hub_port_wrap'>";

        for (var idx = 0; idx < ui_port_cnt; idx++) {
            str_html += "<span class='hub_port " + (arr_port_status[idx] ? "monitor_block_green" : "monitor_block_r") + "'>" + (idx + 1) + "</span>";
        }
        return str_html + "</div>";
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    移除选中和框选块的类
     * 参数:
     *     @param { Promise<String> } select_obj 选中的块;
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2019.12.17
     *      内容 : 所有代码
     ************************************************************************************************/
    function remove_selected_div_class(select_obj) {
        var arr_create_div = arr_create_obj;
        var arr_create_div_len = arr_create_div.length;

        if (arr_create_div_len) {
            for (var idx = 0; idx < arr_create_div_len; idx++) {
                arr_create_div[idx].classList.remove("box_selection_creat_div");
            }
        }

        if (select_obj) {
            select_obj.classList.add("box_selection_creat_div");
        }
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    新创建点的操作; 统一处理; 包括:添加事件监听 && 加入创建点集合 && 绑定数据变动函数
     * 参数:
     *    @param { Promise<String> } obj_point
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-02-07
     *       内容 : 所有代码
    ************************************************************************************************/
    function operation_of_new_create_point(obj_point) {
        if (!obj_point || "object" !== typeof obj_point || "function" !== typeof obj_point.addEventListener) {
            return;
        }

        // 给生成的div添加事件监听
        obj_point.addEventListener("mouseenter", create_div_mouseenter);
        obj_point.addEventListener("keydown", create_div_keydown);
        obj_point.addEventListener("dblclick", create_div_dblclick);

        // 绑定数据变动函数;
        // obj_point.on_val_chg = create_div_on_val_change;
        // 保存生成对象
        arr_create_obj.push(obj_point);
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    更新选中位置; 注意该存储对象内均为 Number;
     * 参数:
     *    @param { Promise<Number> } ui_cur_x 当前框选 & 焦点对象x轴位置值
     *    @param { Promise<Number> } ui_cur_y 当前框选 & 焦点对象y轴位置值
     *    @param { Promise<Number> } b_no_update true=获取位置值 & 不更新回调
     * 返回:
     *    @returns { Promise<Array> } 获取位置值
     * 例子:
     *    NA
     * 备注:
     *    若当前位置无生成块 -> 使用默认宽高
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-09-11
     *       内容 : 所有代码
    ************************************************************************************************/
    function update_select_pos(ui_cur_x, ui_cur_y, b_no_update) {
        if ("number" !== typeof ui_cur_x || "number" !== typeof ui_cur_y) {
            return [];
        }

        // X轴
        var ui_i = 1;
        var ui_pix_x = 0;
        var arr_temp = null;

        while (ui_i < ui_cur_x) {
            arr_temp = m_obj_xywh.get(ui_i, ui_cur_y);

            if (arr_temp) {
                ui_pix_x += arr_temp[0];
            } else {
                ui_pix_x += Number(m_arr_text_key.W);
            }
            ui_i++;
        }

        // Y轴
        var ui_j = 1;
        var ui_pix_y = 0;

        while (ui_j < ui_cur_y) {
            arr_temp = m_obj_xywh.get(ui_cur_x, ui_j);
            if (arr_temp) {
                ui_pix_y += arr_temp[1];
            } else {
                ui_pix_y += Number(m_arr_text_key.H);
            }
            ui_j++;
        }

        if (!b_no_update) {
            if ("function" === typeof m_this.tb_io_on_select_chg) {
                m_this.tb_io_on_select_chg(ui_pix_x, ui_pix_y);
            }
        }

        return [ui_pix_x, ui_pix_y];
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    线条回调; 更新队列dom值; 主要为修改线条key值 -> 修改dom内key,idx
     * 参数:
     *    @param { Promise<String> } dom 生成div dom
     *    @param { Promise<String> } key 连线key
     *    @param { Promise<String> } idx 一组line内下标
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-12-09
     *       内容 : 所有代码
    ************************************************************************************************/
    function update_dom_queue(dom, key, idx) {
        m_this.tb_io_update_text_val(key, idx, null, null, dom);
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    更新选中块; 用于监控页面;
     * 参数:
     *    @param { Promise<String> } str_key 当前块key
     *    @param { Promise<Boolean> } b_dbclick 是否为双击
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-12-06
     *       内容 : 所有代码
    ************************************************************************************************/
    function update_select_key(str_key, b_dbclick) {
        if ("function" === typeof m_this.tb_io_on_select_chg) {
            m_this.tb_io_on_select_chg(str_key, b_dbclick);
        }
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    选中当前对象块; & 调用更新
     * 参数:
     *    @param { Promise<String> }  obj_dom 选中快dom对象
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-12-06
     *       内容 : 所有代码
    ************************************************************************************************/
    function selected_block(obj_dom) {
        if (obj_dom) {
            obj_dom.classList.add("box_selection_creat_div");
            obj_dom.focus();

            if (b_has_line_func) {
                update_select_pos(Number(obj_dom.getAttribute("x")), Number(obj_dom.getAttribute("y")));
            } else {
                update_select_key(obj_dom.getAttribute("KEY"), true);
            }
        }
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    清空数据,重置;
     * 参数:
     *    NA
     * 返回:
     *    NA
     * 例子:
     *    NA
     * 备注:
     *    清空内置数据；包括生成对象; 存储生成dom对象; 框选对象;
     * 修改:
     *   1. 类型 : 创建
     *      作者 : 巫昭雯
     *      时间 : 2020.4.16
     *      内容 : 所有代码
     ************************************************************************************************/
    function clear_data_fun() {
        $("#" + mc_svg_id + " .click_create_div").remove();
        // 清空保存对象
        arr_create_obj = [];
        arr_box_select_obj = [];
        m_obj_xywh.clear();

        if (b_has_line_func && g_obj_line && g_obj_line.clear) {
            g_obj_line.clear();
            g_obj_line.has_mark(false);
            g_obj_line.set_line_point_offst(obj_line_dis);
        }
    }

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    设置每个格子尺寸;
     * 参数:
     *    @param { Promise<String> } w
     *    @param { Promise<String> } h
     *    @param { Promise<String> } 参数1
     * 返回:
     *    @returns { Promise<String> } 参数1
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-11-26
     *       内容 : 所有代码
    ************************************************************************************************/
    function set_rect_size(w,h) {
        if ("number" !== typeof w || "number" !== typeof h) {
            return false;
        }

        if (20 >= w || 20 >= h) {
            return false;
        }

        each_rect_width = w;
        each_rect_height = h;
        return true;
    }


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    渲染数据处理; 封装操作; 每一项单独需要单独操作的调用处理函数fn_deal;
     * 参数:
     *    @param { Promise<Object> } obj_data 单个屏内所有箱体数据; (包括宽高下标，key, 扩展数据等);
     *    @param { Promise<String> } str_type 类型; create_html_monitor_text 参数type值
     *    @param { Promise<Function> } fn_deal 处理函数; 传递参数为 每项数据内的扩展数据(电压，温湿度等数据); 返回块添加的类名称;
     * 返回:
     *    @returns { Promise<Boolean> }
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-12-16
     *       内容 : 所有代码
    ************************************************************************************************/
    function render_data(obj_data, str_type, fn_deal) {
        clear_data_fun();
        if (!mc_util_is_object(obj_data)) {
            return false;
        }

        fn_deal = "function" === typeof fn_deal ? fn_deal : function () {
            return ["monitor_block_grey", "monitor_block_grey", "monitor_block_grey", "monitor_block_grey"];
        };

        var ui_len_line = 0;
        var str_key_val = "";

        for (var key_sp in obj_data) {
            if (Object.hasOwnProperty.call(obj_data, key_sp)) {
                var arr_line = obj_data[key_sp];

                if (!arr_line || !(ui_len_line = arr_line.length)) {
                    continue;
                }

                for (var idx = 0; idx < ui_len_line; idx++) {
                    var obj_item = arr_line[idx];

                    if (!obj_item) {
                        continue;
                    }

                    str_key_val = key_sp + "_" + obj_item.NAME;
                    var arr_class_text = fn_deal(obj_item.EXPAND);
                    var str_text_html = create_html_monitor_text(str_key_val, obj_item.EXPAND, str_type, arr_class_text);
                    var str_html_hub_p = create_html_monitor_hub_port(obj_item.EXPAND);
                    var id = "click_div_" + arr_create_obj.length;

                    create_div_render_monitor(id, obj_item.X, obj_item.Y, key_sp, obj_item.KEY, str_html_hub_p + str_text_html, (obj_item.HUB_BACKUP ? " hub_backup" : "") );
                }
            }
        }

        selected_block(arr_create_obj[0]);
        g_obj_line.update_line();
        return true;
    }


    // ********************************************************************* 接口 ********************************************************************* //
    //  初始化表格布局
    this.tb_io_init = function () {
        if (!m_b_param) {
            return false;
        }

        clear_data_fun();
        init_html();
        return true;
    };


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    设置默认文字信息
     * 参数:
     *    @param { Promise<Number> } bus BUS
     *    @param { Promise<Number> } idx 序号
     *    @param { Promise<Number> } w 宽度
     *    @param { Promise<Number> } h 高度
     * 返回:
     *    @returns { Promise<boolean> } 参数1
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-09-09
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_set_def_text_val = function (bus, idx, w, h) {
        if ("number" !== typeof bus || "number" !== typeof idx || "number" !== typeof w || "number" !== typeof h ) {
            return false;
        }

        var i = 0;
        var html = "";
        var ui_y = 15;

        for (var key in m_arr_text_key) {
            if (Object.hasOwnProperty.call(m_arr_text_key, key)) {
                m_arr_text_key[key] = arguments[i];
                html += "<text class='text_svg' x='" + each_rect_width / 2 + "' y='" + (ui_y) + "' alignment-baseline='middle' text-anchor='middle' fill='#666'>" + (m_arr_text_lang[key] + ":" + arguments[i]) + "</text>";
                ui_y += 18;
                i++;
            }
        }

        m_str_main_text = html;
        // $("#" + pattern_id).html($("#" + pattern_id).html() + html);
        return true;
    };


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    更新选中块信息; 参数格式不为Number时忽略该条数据
     * 参数:
     *    @param { Promise<Number> } bus BUS
     *    @param { Promise<Number> } idx 序号
     *    @param { Promise<Number> } w 宽度
     *    @param { Promise<Number> } h 高度
     *    @param { Promise<Number> } obj 更新该对象的信息; 为空时更新所有选中对象
     * 返回:
     *    @returns { Promise<boolean> } false === 参数全为空
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-09-11
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_update_text_val = function (bus, idx, w, h, obj) {
        if ("undefined" === typeof bus && "undefined" === typeof idx && "undefined" === typeof w && "undefined" === typeof h ) {
            return false;
        }

        var arr_selected_div = [];

        if (obj && "function" === typeof obj.querySelector) {
            arr_selected_div = [obj];
        } else {
            arr_selected_div = arr_box_select_obj;
        }

        var ui_len = arr_selected_div.length;
        var obj_bus = null;
        var obj_idx = null;
        var obj_w = null;
        var obj_h = null;

        for (var i = 0; i < ui_len; i++) {
            var dom = arr_selected_div[i];

            // BUS
            if ("number" === typeof bus && (obj_bus = dom.querySelector(".BUS")) && (Number(obj_bus.getAttribute("BUS")) !== bus) ) {
                obj_bus.innerHTML = m_arr_text_lang.BUS + ":" + bus;
                obj_bus.setAttribute("BUS", bus);
                g_obj_line.modify_key(bus + "", dom, true);
            }
            // 序号
            if ("number" === typeof idx && (obj_idx = dom.querySelector(".IDX")) && (Number(obj_idx.getAttribute("IDX")) !== idx)) {
                obj_idx.innerHTML = m_arr_text_lang.IDX + ":" + idx;
                obj_idx.setAttribute("IDX", idx);
            }
            // 宽度
            if ("number" === typeof w && (obj_w = dom.querySelector(".W")) && (Number(obj_w.getAttribute("W")) !== w)) {
                obj_w.innerHTML = m_arr_text_lang.W + ":" + w;
                obj_w.setAttribute("W", w);
                m_obj_xywh.set(dom.getAttribute("x"), dom.getAttribute("y"), w);
            }
            // 高度
            if ("number" === typeof h && (obj_h = dom.querySelector(".H")) && (Number(obj_h.getAttribute("H")) !== h)) {
                obj_h.innerHTML = m_arr_text_lang.H + ":" + h;
                obj_h.setAttribute("H", h);
                m_obj_xywh.set(dom.getAttribute("x"), dom.getAttribute("y"), null, h);
            }
        }

        return true;
    };


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    设置bus地址值
     * 参数:
     *    @param { Promise<Number> } num 当前地址值
     *    @param { Promise<Number> } max 地址值总数(只在初始化时候设计即可)
     * 返回:
     *    @returns { Promise<Boolean> } 参数1
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-09-11
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_set_bus = function (num, max) {
        if ("number" !== typeof num) {
            return false;
        }

        m_ui_bus_idx = num;
        m_arr_text_key.BUS = m_ui_bus_idx;
        if (g_obj_line && b_has_line_func) {
            g_obj_line.set_color_num(max);
        }
        return true;
    };


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    设置语言表; 用于信息转换
     * 参数:
     *    @param { Promise<Object> } obj 语言表表翻译对象
     * 返回:
     *    @returns { Promise<Boolean> } fasle === 参数错误
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-09-11
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_set_lang = function (obj) {
        if (!mc_util_is_object(obj)) {
            return false;
        }

        obj_lang = obj;
        // mod flash
        m_arr_text_lang.IDX = obj_lang.MC_LANG_MOD_FLASH_IDX || CONST_IDX;
        m_arr_text_lang.W = obj_lang.MC_LANG_MOD_FLASH_W || CONST_W;
        m_arr_text_lang.H = obj_lang.MC_LANG_MOD_FLASH_H || CONST_H;
        // monitor: 箱体序号,温度,湿度,电压; 该模式下为lang_id
        m_arr_text_lang.PORT = obj_lang.MC_LANG_MONITOR_BOX_PORT ? "MC_LANG_MONITOR_BOX_PORT" : "PORT";
        m_arr_text_lang.BOX_IDX = obj_lang.MC_LANG_MONITOR_BOX_IDX ? "MC_LANG_MONITOR_BOX_IDX" : "BOX";
        m_arr_text_lang.TEMP = obj_lang.MC_LANG_MONITOR_TEMP ? "MC_LANG_MONITOR_TEMP" : "Temperature";
        m_arr_text_lang.HUMI = obj_lang.MC_LANG_MONITOR_HUMI ? "MC_LANG_MONITOR_HUMI" : "Humidity";
        m_arr_text_lang.VOL = obj_lang.MC_LANG_MONITOR_VOL ? "MC_LANG_MONITOR_VOL" : "Voltage";
        m_arr_text_lang.STATUS = obj_lang.MC_LANG_MONITOR_PORT_STATUS ? "MC_LANG_MONITOR_PORT_STATUS" : "Voltage";
        m_arr_text_lang.ERROR = obj_lang.MC_LANG_MONITOR_ERROR_PRO ? "MC_LANG_MONITOR_ERROR_PRO" : "Error";
        return true;
    };

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    是否有连线功能; 默认true
     * 参数:
     *    @param { Promise<String> } b_has true=有连线功能
     * 返回:
     *    @returns { Promise<String> } 参数1
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-11-26
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_set_line = function (b_has) {
        if ("boolean" !== typeof b_has) {
            return false;
        }
        b_has_line_func = b_has;
        return true;
    };

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    渲染监控数据; 电压
     * 参数:
     *    @param { Promise<Object> } obj_data 单个屏内所有箱体数据(包括宽高下标，key, 扩展数据等)
     * 返回:
     *    @returns { Promise<Boolean> }
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-11-26
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_render_monitor_vol = function (obj_data) {
        // obj_item_ext 扩展数据
        return render_data(obj_data, "VOL", function (obj_item_ext) {
            if (!obj_item_ext) {
                return [" monitor_block_grey"];
            }

            switch (obj_item_ext.is_abnormal_vol()) {
            case 0:
                return [" monitor_block_b"];
            case 1:
                return [" monitor_block_r"];
            case true:
                return [" monitor_block_grey"];
            default:
                return [" monitor_block_green"];
            }
        });
    };


    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    渲染监控数据; 温湿度; 优先判断温度
     * 参数:
     *    @param { Promise<Object> } obj_data 单个屏内所有箱体数据(包括宽高下标，key, 扩展数据等)
     * 返回:
     *    @returns { Promise<Boolean> }
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-11-26
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_render_monitor_th = function (obj_data) {
        // obj_item_ext 扩展数据
        return render_data(obj_data,"TH" ,function (obj_item_ext) {
            if (!obj_item_ext) {
                return [" monitor_block_grey"];
            }

            var arr_color = [];

            switch (obj_item_ext.is_abnormal_temp()) {
            case 0:
                arr_color.push(" monitor_block_b");
                break;
            case 1:
                arr_color.push(" monitor_block_r");
                break;
            case true:
                arr_color.push(" monitor_block_grey");
                break;
            case false:
                arr_color.push(" monitor_block_green");
                break;
            default:
                break;
            }

            switch (obj_item_ext.is_abnormal_humi()) {
            case 0:
                arr_color.push(" monitor_block_b");
                break;
            case 1:
                arr_color.push(" monitor_block_r");
                break;
            case true:
                arr_color.push(" monitor_block_grey");
                break;
            default:
                arr_color.push(" monitor_block_green");
                break;
            }
            return arr_color;
        });
    };

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    渲染监控数据; 误码率
     * 参数:
     *    @param { Promise<String> } obj_data 数据对象 {BUS:[{BUS,IDX,X,Y,W,H,ROW,COL}, {...}], BUS2:[{},{}]}; BUS内数据为一组line数据,顺序按照
     * 返回:
     *    @returns { Promise<String> } 参数1
     * 例子:
     *    NA
     * 备注:
     *    NA
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2021-12-08
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_render_monitor_err_pro = function (obj_data) {
        // obj_item_ext 扩展数据
        return render_data(obj_data, "ERROR", function (obj_item_ext) {
            if (!obj_item_ext) {
                return [" monitor_block_grey"];
            }

            switch (obj_item_ext.is_abnormal_error_pro()) {
            case 0:
                return [" monitor_block_green"];
            case 1:
                return [" monitor_block_maroon"];
            case 2:
                return [" monitor_block_r"];
            default:
                return [" monitor_block_grey"];
            }
        });
    };

    /************************************************************************************************
     * 类型:
     *    函数
     * 功能:
     *    渲染监控数据: 电压,温湿度,误码率;
     * 参数:
     *    @param { Promise<String> } obj_data 数据对象 {BUS:[{BUS,IDX,X,Y,W,H,ROW,COL}, {...}], BUS2:[{},{}]}; BUS内数据为一组line数据,顺序按照
     * 返回:
     *    @returns { Promise<String> } 参数1
     * 例子:
     *    NA
     * 备注:
     *    调用 render_data 参数二处理函数返回文字颜色值 [电压, 温度, 湿度, 误码率]
     * 修改:
     *    1. 类型 : 创建
     *       作者 : 巫昭雯
     *       时间 : 2022-01-05
     *       内容 : 所有代码
    ************************************************************************************************/
    this.tb_io_rander_monitor_data = function (obj_data) {
        // obj_item_ext 扩展数据
        return render_data(obj_data, "all", function (obj_item_ext) {
            if (!obj_item_ext) {
                return ["monitor_block_grey", "monitor_block_grey", "monitor_block_grey", "monitor_block_grey"];
            }
            var str_color_def = "monitor_block_green";
            var obj_color_code = {
                0: "monitor_block_b",
                1: "monitor_block_r",
                true: "monitor_block_grey"
                // :"monitor_block_green", 其他状态(数据正常)
            };

            var res_vol = obj_item_ext.is_abnormal_vol();
            var res_temp = obj_item_ext.is_abnormal_temp();
            var res_humi = obj_item_ext.is_abnormal_humi();
            var arr_color = [
                obj_color_code[res_vol] ? obj_color_code[res_vol] : str_color_def,
                obj_color_code[res_temp] ? obj_color_code[res_temp] : str_color_def,
                obj_color_code[res_humi] ? obj_color_code[res_humi] : str_color_def
            ];

            switch (obj_item_ext.is_abnormal_error_pro()) {
            case 0:
                arr_color.push(" monitor_block_green");
                break;
            case 1:
                arr_color.push(" monitor_block_maroon");
                break;
            case 2:
                arr_color.push(" monitor_block_r");
                break;
            default:
                arr_color.push(" monitor_block_grey");
                break;
            }
            return arr_color;
        });
    };


    // 选中变动
    this.tb_io_on_select_chg = function () { };
    // 滚动条滚动联动
    this.tb_io_on_scroll = function () { };
    return true;
}


